package com.example.lambda;


import com.example.model.Person;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created by zjq on 2018/11/21.
 */
public class LambdaTest {


    public static void main(String[] args) {
        LambdaTest l = new LambdaTest();
        l.test1();
        l.test2();
        l.test3();
    }

    public void test1() {
        // Java 8之前：
        List<String> features2 = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
        for (String f : features2) {
            System.out.println(f);
        }
        System.out.println("==========================================================================================");
        // Java 8之后：
        List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
        features.forEach(n -> System.out.println(n));
        System.out.println("==========================================================================================");
        // 使用Java 8的方法引用更方便，方法引用由::双冒号操作符标示，
        // 看起来像C++的作用域解析运算符
        features.forEach(System.out::println);
        System.out.println("=============================================================================================");
    }

    /**
     * 将 list中元素 变成小写
     */
    public void test2() {
        List<String> proNames = Arrays.asList(new String[]{"Ni", "Hao", "Lambda"});

        List<String> lowercaseNames2 = proNames.stream().map(name -> name.toLowerCase()).collect(Collectors.toList());

        lowercaseNames2.forEach(n -> System.out.println(n));

    }

    /**
     * 利用 lambda表达式 给 集合中每个元素 赋值 并且排序
     */
    public void test3() {
        System.out.println("***********************************************************************************");
        Person p1 = new Person(6, "张三", 98.2);
        Person p2 = new Person(2, "张三", 88.2);
        Person p3 = new Person(3, "王无", 68.2);
        Person p4 = new Person(4, "赵六", 90.8);
        // 以前的方式
        List<Person> list = Arrays.asList(p1, p2, p3, p4);
        for (Person l : list) {
            l.setScore(l.getScore() * 10);
        }
        System.out.println("***********************************************************************************");
        System.out.println("给分个人分数乘100");
        //使用lambda表达式 循环给list 赋值 只有一则不需要加{ }
        list.stream().forEach(n -> n.setScore(n.getScore() * 10));
//        list.stream().forEach(n ->{
//            if(n.getScore()>8000){
//                n.setScore(n.getScore() * 10);
//            }
//        });
        list.forEach(n -> System.out.println(n));

        //排序 ，以分数高低 排序 产生一个新流
        System.out.println("用 stram 排序");
        Stream<Person> stream = list.stream()
                .sorted((x, y) -> { //使流中的序列两两进行比较 分数相同，比名字
                    if (x.getScore() == y.getScore()) {
                        return x.getName().compareTo(y.getName());
                    } else {
                        return x.getScore() > y.getScore() ? 1 : -1;
                    }
                });

        stream.forEach(System.out::println);

        //list集合的排序 根据id正序 123
        System.out.println("list集合排序用Comparator  从小到大(按照id)");
        Collections.sort(list, Comparator.comparing(Person::getId));
        list.stream().forEach(n -> System.out.println(n));

        System.out.println("=============================================");

        //反序排序  从大到小
        System.out.println("list集合排序用Comparator  从大到小(按照id)");
        Comparator<Person> comparator = (h1, h2) -> Integer.valueOf(h1.getId()).compareTo(Integer.valueOf(h2.getId()));
        list.sort(comparator.reversed());
        list.stream().forEach(n -> System.out.println(n));


        System.out.println("=====利用lambda表达式排序===================");

        List<Person> list2 = Arrays.asList(p1, p2, p3, p4);

        System.out.println("lambda表达式 从小到大");
        list2.sort((Person h1, Person h2) -> Integer.compare(h1.getId(), h2.getId()));
        list2.stream().forEach(n -> System.out.println(n));

        System.out.println("lambda表达式 从大到小");
        list2.sort((Person h1, Person h2) -> Integer.valueOf(h2.getId()).compareTo(h1.getId()));
        list2.stream().forEach(n -> System.out.println(n));

        /**
         *  .stream().sorted.....collect()：返回新的有序集合，原集合顺序不变
         *    .sort...：返回void，原集合顺序变为有序
         */


        System.out.println("lambda表达式 stram 流 从小到大s");
        List<Person> list222 = list2.stream().sorted(Comparator.comparing(Person::getId)).collect(Collectors.toList());
        list222.stream().forEach(System.out::println);

        System.out.println("lambda表达式 stram 流 从大到小");
        List<Person> list333 = list2.stream().sorted(Comparator.comparing(Person::getId).reversed()).collect(Collectors.toList());
        list333.stream().forEach(System.out::println);


        System.out.println("=====利用lambda表达式 使用多个条件进行排序==================");
        Person p11 = new Person(6, "张三", 78.2);
        Person p22 = new Person(2, "张三", 88.2);
        Person p33 = new Person(3, "王无", 68.2);
        Person p44 = new Person(4, "赵六", 90.8);

        List<Person> list3 = Arrays.asList(p11, p22, p33, p44);
        //先根据名称 从小到大排序 若名字相同，则将分数低的排在前面
        Comparator<Person> comparator3 = (h1, h2) -> {
            //若名字相同。比分数
            if (h1.getName().equalsIgnoreCase(h2.getName())) {
                return Double.compare(h1.getScore(), h2.getScore());
            }
            return h1.getName().compareTo(h2.getName());
        };
//        list3.sort(comparator3.reversed());//反序
        list3.sort(comparator3);//正序
        list3.stream().forEach(n -> System.out.println(n));

        System.out.println("=====利用lambda表达式 使用多个条件进行排序 更优雅的实现方式==================");
        Person p111 = new Person(6, "张三", 78.2);
        Person p222 = new Person(2, "李四", 78.2);
        Person p333 = new Person(3, "王无", 68.2);
        Person p444 = new Person(4, "赵六", 90.8);
        List<Person> list4 = Arrays.asList(p111, p222, p333, p444);

        //先根据分数高低排序 ，分数相同的再根据学号排序
        list4.sort(Comparator.comparing(Person::getScore).thenComparing(Person::getId));//正序
        list4.stream().forEach(n -> System.out.println(n));
        System.out.println("================");
        Collections.reverse(list4);
        list4.stream().forEach(n -> System.out.println(n));


        // listMap的排序


        List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
        Map<String, Object> map1 = new HashMap<String, Object>();
        map1.put("id", "1");
        map1.put("name", "p");
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("id", "2");
        map2.put("name", "h");
        Map<String, Object> map3 = new HashMap<String, Object>();
        map3.put("id", "3");
        map3.put("name", "f");
        listMap.add(map1);
        listMap.add(map3);
        listMap.add(map2);


        /**
         *  .map会返回新的集合 ,但是原集和顺序没变
         */
        Stream<String> stream1 = listMap.stream().map(n -> "001: " + n.get("id"));
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        stream1.forEach(n -> System.out.println(n));
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        listMap.stream().map(n -> "002: " + n.get("id")).forEach(n -> {
            System.out.println(n);
        });

        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        listMap.stream().forEach(System.out::println);
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        listMap.stream().forEach(n -> {
            n.put("name", n.get("name") + "qqqq");
        });
        listMap.stream().forEach(n -> {
            System.out.println(n);
        });


        //排序前
        System.out.println("排序前");
        for (Map<String, Object> map : listMap) {
            System.out.println(map.get("id"));
        }

        //匿名方式
        System.out.println("匿名方式排序");
        Collections.sort(listMap, new Comparator<Map<String, Object>>() {
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                String name1 = (String) o1.get("id");//name1是从你list里面拿出来的一个
                String name2 = (String) o2.get("id"); //name是从你list里面拿出来的第二个name    
                return name1.compareTo(name2);
            }
        });
        System.out.println("排序前");
        Collections.sort(listMap, (o1, o2) -> {
            String name1 = (String) o1.get("id");
            String name2 = (String) o2.get("id");
            return name2.compareTo(name1);
        });


    }
}
